package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.base.ResponseResult;
import com.zzyl.constant.AccraditationRecordConstant;
import com.zzyl.dto.BillDto;
import com.zzyl.dto.ContractDto;
import com.zzyl.entity.*;
import com.zzyl.enums.ContractStatusEnum;
import com.zzyl.mapper.*;
import com.zzyl.service.*;
import com.zzyl.utils.UserThreadLocal;
import com.zzyl.vo.ContractVo;
import com.zzyl.vo.RecordVo;
import com.zzyl.vo.retreat.ElderVo;
import io.swagger.util.Json;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 合同 Service 实现类
 */
@Service
public class ContractServiceImpl implements ContractService {

    @Autowired
    private ContractMapper contractMapper;

    @Resource
    private MemberService memberService;

    /**
     * 根据id查询合同
     * @param id 合同id
     * @return 合同实体类
     */
    @Override
    public ContractVo getById(Long id) {
        Contract contract = contractMapper.selectByPrimaryKey(id);
        return BeanUtil.toBean(contract, ContractVo.class);
    }

    /**
     * 更新合同
     * @param contractDto 合同dto
     * @return 更新结果
     */
    @Override
    public int update(ContractDto contractDto) {
        Contract contract = new Contract();
        BeanUtils.copyProperties(contractDto, contract);
        return contractMapper.updateByPrimaryKey(contract);
    }

    /**
     * 根据id删除合同
     * @param id 合同id
     * @return 删除结果
     */
    @Override
    public int deleteById(Long id) {
        return contractMapper.deleteByPrimaryKey(id);
    }

    /**
     * 分页查询合同信息
     *
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @param contractNo 合同编号
     * @param elderName 老人姓名
     * @param status 合同状态
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 分页结果
     */
    @Override
    public PageResponse<ContractVo> selectByPage(Integer pageNum, Integer pageSize, String contractNo, String elderName,
                                                 Integer status, LocalDateTime startTime, LocalDateTime endTime) {
        PageHelper.startPage(pageNum, pageSize);

        // 通过丙方手机号关联合同
        String phone = null;
        Long userId = UserThreadLocal.getUserId();
        if (ObjectUtil.isNotEmpty(userId)) {
            Member byId = memberService.getById(userId);
            if (ObjectUtil.isNotEmpty(byId)) {
                phone = byId.getPhone();
            }
        }
        Page<List<Contract>> page = contractMapper.selectByPage(phone, contractNo, elderName, status, startTime, endTime);
        return PageResponse.of(page, ContractVo.class);
    }

    @Override
    public List<Contract> listAllContracts() {
        return contractMapper.listAllContracts();
    }

    @Override
    public void updateBatchById(List<Contract> updateList) {
        List<Long> collect = updateList.stream().map(Contract::getId).collect(Collectors.toList());
        contractMapper.batchUpdateByPrimaryKeySelective(collect, updateList.get(0).getStatus());
    }

    @Override
    public List<ContractVo> listByMemberPhone(String phone) {
        return contractMapper.listByMemberPhone(phone);
    }

    @Autowired
    private CheckInMapper checkInMapper;

    @Autowired
    private ElderMapper elderMapper;

    @Autowired
    private BalanceMapper balanceMapper;

    @Autowired
    private CheckInConfigMapper checkInConfigMapper;

    @Autowired
    private BedMapper bedMapper;

    @Autowired
    private BillService billService;

    @Autowired
    private NursingTaskService nursingTaskService;

    @Autowired
    private ActFlowCommService actFlowCommService;

    @Autowired
    private AccraditationRecordService accraditationRecordService;

    /**
     * 签约
     * @param contractDto
     * @return
     */
    @Override
    public ResponseResult sign(ContractDto contractDto) {

        //更新入住审核状态
        CheckIn checkIn = checkInMapper.selectByPrimaryKey(contractDto.getCheckInId());
        checkIn.setStatus(CheckIn.Status.FINISHED.getCode());
        checkInMapper.updateByPrimaryKeySelective(checkIn);

        //更新老人状态
        Elder elder = elderMapper.selectByPrimaryKey(checkIn.getElderId());
        elder.setStatus(1);
        elderMapper.updateByPrimaryKey(elder);

        //查询入住配置
        CheckInConfig checkInConfig = checkInConfigMapper.findCurrentConfigByElderId(checkIn.getElderId());

        //新增老人余额
        Balance balance = new Balance();
        balance.setPrepaidBalance(new BigDecimal(0));//预缴款
        balance.setDepositAmount(checkInConfig.getDepositAmount());//押金
        balance.setArrearsAmount(new BigDecimal(0));//欠费
        balance.setStatus(0);
        balance.setBedNo(elder.getBedNumber());
        balance.setElderId(elder.getId());
        balance.setElderName(elder.getName());
        balanceMapper.insert(balance);

        //更新床位状态
        Bed bed = bedMapper.getBedById(elder.getBedId());
        bed.setBedStatus(1);
        bedMapper.updateBed(bed);

        //生成首月账单
        BillDto billDto = new BillDto();
        LocalDateTime checkInStartTime = checkInConfig.getCheckInStartTime();
        String dateStr = LocalDateTimeUtil.format(checkInStartTime, "yyyy-MM");
        billDto.setBillMonth(dateStr);//yyyy-MM
        billDto.setElderId(elder.getId());
        billService.createMonthBill(billDto);

        //生成护理任务
        ElderVo elderVo = BeanUtil.toBean(elder, ElderVo.class);
        nursingTaskService.createMonthTask(elderVo,contractDto.getSignDate(),checkInStartTime);

        //保存合同
        Contract contract = BeanUtil.toBean(contractDto, Contract.class);
        //入住编号
        contract.setCheckInNo(checkIn.getCheckInCode());
        contract.setElderId(elder.getId());
        contract.setElderName(elder.getName());
        //合同状态
        contract.setStatus(ContractStatusEnum.PENDING_EFFECTIVE.getOrdinal());
        contractMapper.insert(contract);

        //用户数据
        String subject = UserThreadLocal.getSubject();
        User user = JSON.parseObject(subject, User.class);

        //完成任务
        actFlowCommService.completeProcess("",contractDto.getTaskId(),user.getId().toString(),1,CheckIn.Status.FINISHED.getCode());

        //保存操作记录
        RecordVo recoreVo = getRecordVo(
                checkIn,
                user,
                AccraditationRecordConstant.AUDIT_STATUS_PASS,
                "同意",
                "法务处理-签约办理",
                "",
                null,
                AccraditationRecordConstant.RECORD_HANDLE_TYPE_PROCESSED);
        accraditationRecordService.insert(recoreVo);

        return ResponseResult.success();

    }

    /**
     * 封装审核记录参数
     *
     * @param checkIn      入住对象
     * @param user         当前登录用户
     * @param status       审核状态
     * @param option       操作意见
     * @param step         当前步骤
     * @param nextSetp     下一步操作人
     * @param nextAssignee 下一个审核人
     * @param handleType   处理类型（0:已审批，1：已处理）
     * @return
     */
    private RecordVo getRecordVo(CheckIn checkIn, User user, Integer status, String option, String step, String nextSetp, Long nextAssignee, Integer handleType) {

        RecordVo recordVo = new RecordVo();
        recordVo.setId(checkIn.getId());
        recordVo.setType(AccraditationRecordConstant.RECORD_TYPE_CHECK_IN);
        recordVo.setFlowStatus(checkIn.getFlowStatus());
        recordVo.setHandleType(handleType);
        recordVo.setStatus(status);
        recordVo.setOption(option);
        recordVo.setNextStep(nextSetp);
        recordVo.setNextAssignee(nextAssignee);
        recordVo.setUserId(user.getId());
        recordVo.setStep(step);
        recordVo.setRealName(user.getRealName());

        return recordVo;
    }
}


